//
//  MFWUserLoginManager.m
//  MFWSdk
//
//  Created by Song Xiaofeng on 13-8-6.
//  Copyright (c) 2013年 Mafengwo Inc. All rights reserved.
//

#import "MFWUserLoginManager.h"
#import "MFWSDKNotificationConsts.h"
#import "MULLoginManager.h"

NSString *const kMFWLoginError_Str_Msg =kMULLoginErrorMessage;
NSString *const kMFWLoginError_Domain = kMULLoginErrorDomain;

@interface MFWSdkEnvironment()
@property(nonatomic, strong)id<IMFWShare>mfwShare;
@end

@interface MFWUserLoginManager()
@property(nonatomic, copy)UserLoginFinished loginCallback;
@property(nonatomic, copy)UserRegisterFinished registerCallback;
@property(nonatomic, copy)UserLoginFinished thirdPartLoginCallback;
@end

@implementation MFWUserLoginManager

+ (MFWUserLoginManager *)sharedInstance;
{
    static MFWUserLoginManager *_sharedInstance = nil;
	if (_sharedInstance == nil)
	{
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _sharedInstance = [[MFWUserLoginManager alloc] init];
			
        });
	}
	
	return _sharedInstance;
}

+ (void)setThirdPartBindingNavigationConfigBlock:(void(^)(UINavigationController *navigationController)) block;
{
    [MULLoginManager sharedInstance].bindNavigationConfigBlock = block;
}

- (void)logout;
{
//    [self logoutCurrentUser];
    [[NSNotificationCenter defaultCenter] postNotificationName:kSDK_Notify_UserWillLogout object:nil];
}

- (void)accessTokenFinised:(NSData*)responseData parsedJson:(MFWJson*)json error:(NSError*)error
{

    if (json && !error)
    {
        error = [MFWServiceUtils parseMFWServiceError:json];
    }
    
    if (error)
    {// obtain accesstoken failed
        if (self.loginCallback)
        {
            if ([error.userInfo intValueForKey:kMFWErrorInfo_Int_StatusCode] == 401)
            {
                error = [NSError errorWithDomain:MFWErrorDomain code:10000 userInfo:@{kMFWErrorInfo_Int_StatusCode: @401, kMFWErrorInfo_Str_Msg : @"用户名或密码错误"}];
            }
            self.loginCallback(NO, nil, error);
            
            self.loginCallback = nil;
        }
    }
    else
    {// obtain accessToken and user info successfull
        if ([self handleUserTokenSucc:json])
        {
            if (self.loginCallback)
            {
                self.loginCallback(YES, [MFWSdkEnvironment sharedInstance].userInfo, nil);
                
                self.loginCallback = nil;
            }
        }
        else if (self.loginCallback)
        {
            self.loginCallback(NO, nil, nil);
            
            self.loginCallback = nil;
        }
    }
}

- (void)thirdPartLoginFinished:(NSData*)responseData parsedJson:(MFWJson*)json error:(NSError*)error
{
    if (json && !error)
    {
        error = [MFWServiceUtils parseMFWServiceError:json];
    }
    
    if (error)
    {// obtain accesstoken failed
        if (self.thirdPartLoginCallback)
        {
            if ([error.userInfo intValueForKey:kMFWErrorInfo_Int_StatusCode] == 401)
            {
                error = [NSError errorWithDomain:MFWErrorDomain code:10000 userInfo:@{kMFWErrorInfo_Int_StatusCode: @401, kMFWErrorInfo_Str_Msg : @"用户名或密码错误"}];
            }
            self.thirdPartLoginCallback(NO, nil, error);
            
            self.thirdPartLoginCallback = nil;
        }
    }
    else
    {// obtain accessToken and user info successfull
        if ([self handleUserTokenSucc:json])
        {
            if (self.thirdPartLoginCallback)
            {
                self.thirdPartLoginCallback(YES, [MFWSdkEnvironment sharedInstance].userInfo, nil);
                
                self.thirdPartLoginCallback = nil;
            }
        }
        else if (self.thirdPartLoginCallback)
        {
            self.thirdPartLoginCallback(NO, nil, nil);
            
            self.thirdPartLoginCallback = nil;
        }
    }

}

- (void)accountRegisterFinished:(NSData*)responseData parsedJson:(MFWJson*)json error:(NSError*)error
{
    if (json && !error)
    {
        error = [MFWServiceUtils parseMFWServiceError:json];
    }
    
    if (error)
    {// obtain accesstoken failed
        if (self.registerCallback)
        {
            if ([error.userInfo intValueForKey:kMFWErrorInfo_Int_StatusCode] == 401)
            {
                error = [NSError errorWithDomain:MFWErrorDomain code:10000 userInfo:@{kMFWErrorInfo_Int_StatusCode: @401, kMFWErrorInfo_Str_Msg : @"用户名或密码错误"}];
            }
            self.registerCallback(NO, nil, error);
            
            self.registerCallback = nil;
        }
    }
    else
    {// obtain accessToken and user info successfull
        if ([self handleUserTokenSucc:json])
        {
            if (self.registerCallback)
            {
                self.registerCallback(YES, [MFWSdkEnvironment sharedInstance].userInfo, nil);
                
                self.registerCallback = nil;
            }
        }
        else if (self.registerCallback)
        {
            self.registerCallback(NO, nil, nil);
            
            self.registerCallback = nil;
        }
            
    }
}

- (BOOL)handleUserTokenSucc:(MFWJson*)json
{
    MFWJson *jsonData = [json jsonForKey:@"data"];
    
    [[MFWSdkEnvironment sharedInstance].userInfo updateInfoFromUserJsonData:jsonData];
    
//    NSString *oauthToken = [jsonData stringValueForKey:@"oauth_token"];
//    NSString *oauthSecret = [jsonData stringValueForKey:@"oauth_token_secret"];
//    NSString *uid = [MFWSdkEnvironment sharedInstance].userInfo.uid;
    
    
    
    // login success
    [[NSNotificationCenter defaultCenter] postNotificationName:kSDK_Notify_UserDidLogin object:nil userInfo:jsonData.jsonObj];
    
    return YES;
}

- (MFWUserInfo*)parseUserInfo:(NSDictionary*)baseInfo extraInfo:(NSDictionary*)extraInfo
{
    if (!baseInfo && !extraInfo)
    {
        return nil;
    }
    
    MFWUserInfo *userInfo = [MFWSdkEnvironment sharedInstance].userInfo;
    userInfo.uid = [baseInfo stringValueForKey:@"id"];
    userInfo.nickName = [baseInfo stringValueForKey:@"username"];
    if (extraInfo)
    {
        userInfo.logoUrl = [extraInfo stringValueForKey:@"header"];
        userInfo.gender = [extraInfo intValueForKey:@"gender"];
        userInfo.ucity = [extraInfo stringValueForKey:@"location"];
        userInfo.uIntro = [extraInfo stringValueForKey:@"desc"];
    }
     
    if ([userInfo.uid length] > 0)
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            [userInfo synchronizeToDisk];
        });
    }

    [MFWSdkEnvironment sharedInstance].accessToken = [baseInfo stringValueForKey:@"oauth_token"];
    [MFWSdkEnvironment sharedInstance].tokenSecret = [baseInfo stringValueForKey:@"oauth_token_secret"];
    
    return userInfo;
}

- (BOOL)loginWithMFWUserName:(NSString*)username password:(NSString*)password finisheHandler:(UserLoginFinished)handler;
{
    
    if ([MFWStringUtils isEmptyString:username] || [MFWStringUtils isEmptyString:password])
    {
        return NO;
    }
    
    self.loginCallback = handler;
    
    __weak MFWUserLoginManager* wself = self;
    [[MULLoginManager sharedInstance] loginWithMFWAccount:username
                                                 password:password
                                                 openUDID:[MFWSdkEnvironment sharedInstance].openUDID
                                            finishedBlock:^(BOOL success, NSDictionary *baseInfo, NSDictionary *extraInfo, NSError *error) {
        
        MFWUserLoginManager *sself = wself;
        if (sself)
        {
            MFWUserInfo *userInfo = [self parseUserInfo:baseInfo extraInfo:extraInfo];
            
            sself.loginCallback(!error, userInfo, error);
            
            if (!error)
            {
                // login success
                [[NSNotificationCenter defaultCenter] postNotificationName:kSDK_Notify_UserDidLogin object:nil userInfo:baseInfo];
            }
        }
    }];
    
    return YES;
}

- (BOOL)do3rdLoginWithUid:(NSString*)userid
                     type:(NSString*)type
                     name:(NSString*)name
                   header:(NSString*)header
                 location:(NSString*)location
                   gender:(NSString*)gender
                  unionId:(NSString*)unionId
            finishHandler:(UserLoginFinished) handler {
    if ([MFWStringUtils isEmptyString:userid] || [MFWStringUtils isEmptyString:type])
    {
        return NO;
    }
    
    self.loginCallback = handler;
    
    __weak MFWUserLoginManager* wself = self;
    [[MULLoginManager sharedInstance] loginWith3rdUid:userid type:type name:name header:header location:location gender:gender                unionId:unionId                            finishedBlock:^(BOOL success, NSDictionary *baseInfo, NSDictionary *extraInfo, NSError *error) {
                                                
                                                MFWUserLoginManager *sself = wself;
                                                if (sself)
                                                {
                                                    MFWUserInfo *userInfo = [self parseUserInfo:baseInfo extraInfo:extraInfo];
                                                    sself.loginCallback(!error, userInfo, error);
                                                    
                                                    if (!error)
                                                    {
                                                        // login success
                                                        [[NSNotificationCenter defaultCenter] postNotificationName:kSDK_Notify_UserDidLogin object:nil userInfo:baseInfo];
                                                    }
                                                }
                                            }];
    
    return YES;
}

-(BOOL)loginWithOIDUserName:(NSString *)username password:(NSString *)password finisheHandler:(UserLoginFinished)handler{
    if ([MFWStringUtils isEmptyString:username] || [MFWStringUtils isEmptyString:password])
    {
        return NO;
    }
    
    self.loginCallback = handler;
    
    __weak MFWUserLoginManager* wself = self;
    [[MULLoginManager sharedInstance] loginWithMFWAccount:username
                                                 password:password
                                                 openUDID:nil
                                            finishedBlock:^(BOOL success, NSDictionary *baseInfo, NSDictionary *extraInfo, NSError *error) {
                                                
                                                MFWUserLoginManager *sself = wself;
                                                if (sself)
                                                {
                                                    MFWUserInfo *userInfo = [self parseUserInfo:baseInfo extraInfo:extraInfo];
                                                    
                                                    sself.loginCallback(!error, userInfo, error);
                                                    
                                                    if (!error)
                                                    {
                                                        // login success
                                                        [[NSNotificationCenter defaultCenter] postNotificationName:kSDK_Notify_UserDidLogin object:nil userInfo:baseInfo];
                                                    }
                                                }
                                            }];
    
    return YES;

}

- (BOOL)registerWithOIDUserName:(NSString*)username password:(NSString*)password email:(NSString *)email finisheHandler:(UserRegisterFinished)handler{
    if ([MFWStringUtils isEmptyString:username] || [MFWStringUtils isEmptyString:password])
    {
        return NO;
    }
    
    self.registerCallback = handler;
    
    __weak MFWUserLoginManager* wself = self;
    [[MULLoginManager sharedInstance] registerWithMFWAccount:username password:password nickName:nil
                                                    openUDID:nil
                                                       email:email
                                               finishedBlock:^(BOOL success, NSDictionary *baseInfo, NSDictionary *extraInfo, NSError *error) {
                                                   
                                                   MFWUserLoginManager *sself = wself;
                                                   if (sself)
                                                   {
                                                       MFWUserInfo *userInfo = [self parseUserInfo:baseInfo extraInfo:extraInfo];
                                                       sself.registerCallback(!error, userInfo, error);
                                                       
                                                       if (!error)
                                                       {
                                                           // login success
                                                           [[NSNotificationCenter defaultCenter] postNotificationName:kSDK_Notify_UserDidLogin object:nil userInfo:baseInfo];
                                                       }
                                                   }
                                               }];
    
    return YES;
}

- (BOOL)registerWithMFWUserName:(NSString*)username password:(NSString*)password nickName:(NSString*)nickName finisheHandler:(UserRegisterFinished)handler;
{
    if ([MFWStringUtils isEmptyString:username] || [MFWStringUtils isEmptyString:password])
    {
        return NO;
    }
    
    self.registerCallback = handler;
    
    __weak MFWUserLoginManager* wself = self;
    [[MULLoginManager sharedInstance] registerWithMFWAccount:username password:password nickName:nickName
                                               openUDID:[MFWSdkEnvironment sharedInstance].openUDID
                                                email:nil
                                               finishedBlock:^(BOOL success, NSDictionary *baseInfo, NSDictionary *extraInfo, NSError *error) {
        
        MFWUserLoginManager *sself = wself;
        if (sself)
        {
            MFWUserInfo *userInfo = [self parseUserInfo:baseInfo extraInfo:extraInfo];
            sself.registerCallback(!error, userInfo, error);
            
            if (!error)
            {
                // login success
                [[NSNotificationCenter defaultCenter] postNotificationName:kSDK_Notify_UserDidLogin object:nil userInfo:baseInfo];
            }
        }
    }];
    
    return YES;
}

- (BOOL)loginWithThirdParty:(MFWShareType)shareType startBind:(void(^)())startBindBlock finisheHandler:(UserLoginFinished)handler;
{
    if (shareType != MFWShareTypeSinaWeibo
        && shareType != MFWShareTypeQQSpace
        && shareType != MFWShareTypeRenren
        && shareType != MFWShareTypeWeixiSession)
    {
        return NO;
    }

    
    id<IMFWShare> mfwShare = [MFWSdkEnvironment sharedInstance].mfwShare;
    if (!mfwShare)
    {
        return NO;
    }
    
    [mfwShare cancelAuthWithType:shareType];
    
    self.thirdPartLoginCallback = handler;
    
    __weak MFWUserLoginManager* wself = self;
    [mfwShare getUserInfoWithType:shareType result:^(MFWShareType type, id<IMFWShareUserInfo> userInfo, MFWShareResultState state, NSString *errorMsg)
    {
        __strong MFWUserLoginManager* sself = wself;
        
        if (state == MFWShareResultStateSuccess)
        {
            id<IMFWShareCredentialInfo> credentialInfo = [mfwShare getCredentialInfo:shareType];
            
            
            MULLoginThirdPartType thirdPartType = 0;
            NSString *thirdPartAppKey = [mfwShare getAppKeyWithType:type];
            
            if (type == MFWShareTypeSinaWeibo)
            {
                thirdPartType = kThirdPart_Weibo;
            }
            else if (type == MFWShareTypeQQSpace)
            {
                thirdPartType = kThirdPart_Qzone;
            }
            else if ( type == MFWShareTypeRenren)
            {
                thirdPartType = kThirdPart_Renren;
            }
            else if (type == MFWShareTypeWeixiSession)
            {
                thirdPartType = kThirdPart_WeChat;
            }
            
            NSString *token = [credentialInfo token];
            NSDate *expired = [credentialInfo expired];
            NSString *sourceUID = [credentialInfo uid];
            NSString *uniqid = nil;
            
            if (type == MFWShareTypeWeixiSession)
            {
                thirdPartAppKey = [mfwShare getAppIdWithType:type];
                uniqid = [[userInfo sourceData] stringValueForKey:@"unionid"];
            }
            
            [[MULLoginManager sharedInstance] loginWith3rdPartAppKey:thirdPartAppKey
                                                   clientAccessToken:token
                                                        wechatUniqid:uniqid
                                                           sourceUID:sourceUID
                                                         expiredDate:expired
                                                       thirdPartType:thirdPartType
                                                            nickName:[userInfo nickname]
                                                             logoUrl:[userInfo profileImage]
                                                            openUDID:[MFWSdkEnvironment sharedInstance].openUDID
                                                      startBindBlock:startBindBlock
                                                       finishedBlock:^(BOOL success, NSDictionary *baseInfo, NSDictionary *extraInfo, NSError *error) {
                                                           if (sself.thirdPartLoginCallback)
                                                           {
                                                               MFWUserInfo *userInfo = [self parseUserInfo:baseInfo extraInfo:extraInfo];
                                                               sself.thirdPartLoginCallback(!error, userInfo, error);
                                                               
                                                               if (!error)
                                                               {
                                                                   // login success
                                                                   [[NSNotificationCenter defaultCenter] postNotificationName:kSDK_Notify_UserDidLogin object:nil userInfo:baseInfo];
                                                               }
                                                           }
                                                       }];
//            if (sself)
//            {
//                NSDictionary *params = [self _buildUniversalUserInfoFromThirdPartUserInfo:userInfo credentialInfo:credentialInfo thirdPartType:type];
//                [sself _exchangeMFWTokenFrom3rdPartInfo:params thirdPartType:type];
//            }
        }
        else
        {
            if (sself.thirdPartLoginCallback)
            {
                sself.thirdPartLoginCallback(NO, nil, nil);
            }
        }
    }];
    
    return YES;
}

- (void)logoutCurrentUser
{
    MFWHttpRequest* request = [MFWHttpRequest dataRequest];
    request.httpMethod = kRequestHttpMethodPost;
    request.requestApi = kAPI_Logout;
    request.requestCompleteCallback = ^(MFWHttpRequest *request, NSData* responseData, MFWJson* parsedJson, NSError* error) {

    };
    [[MFWHttpEngine sharedInstance] addRequest:request];
}

//- (NSDictionary*)_buildUniversalUserInfoFromThirdPartUserInfo:(id<IMFWShareUserInfo>)userInfo credentialInfo:(id<IMFWShareCredentialInfo>)credentialInfo thirdPartType:(MFWShareType)thirdPartType
//{
//    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:10];
//    
//    DLog(@"sourceData >> \n %@", userInfo.sourceData);
//    
//    NSString *appKey = [[MFWSdkEnvironment sharedInstance].mfwShare getAppKeyWithType:thirdPartType];
//    NSString *accessToken = nil;
//    NSString *sourceUID = nil;
//    
//    switch (thirdPartType) {
//        case MFWShareTypeSinaWeibo:
//            accessToken = [credentialInfo token];
//            sourceUID = [credentialInfo uid];
//            break;
//        case MFWShareTypeRenren:
//            accessToken = [credentialInfo token];
//            sourceUID = [credentialInfo uid];
//            break;
//        case MFWShareTypeQQSpace:
//            accessToken = [credentialInfo token];
//            sourceUID = [credentialInfo uid];
//            break;
//            // todo by hanxin 如果将来支持更多第三方登录，则需在这里增加代码
//        default:
//            break;
//    }
//    
//    [params setValue:appKey forKey:@"app_key"];
//    [params setValue:accessToken forKey:@"client_access_token"];
//    [params setValue:sourceUID forKey:@"source_id"];
//    
//    return params;
//}

//- (void)_exchangeMFWTokenFrom3rdPartInfo:(NSDictionary*)thirdPartInfo thirdPartType:(MFWShareType)thirdPartType
//{
//    if (self.thirdPartLoginCallback)
//    {
////        self.thirdPartLoginCallback(NO, nil, nil);
//        NSString *appKey = [thirdPartInfo stringValueForKey:@"app_key"];
//        NSString *accessToken = [thirdPartInfo stringValueForKey:@"client_access_token"];
//        NSString *sourceUID = [thirdPartInfo stringValueForKey:@"source_id"];
//        
//        MFWHttpRequest *request = [MFWHttpRequest dataRequest];
//        [request.requestParams setValue:appKey forKey:@"app_key"];
//        [request.requestParams setValue:accessToken forKey:@"client_access_token"];
//        [request.requestParams setValue:sourceUID forKey:@"source_id"];
//        [request.requestParams setValue:[NSString stringWithFormat:@"%d", thirdPartType] forKey:@"type"];
//        
//        request.httpMethod = kRequestHttpMethodPost;
//        request.requestUrl = kAPI_3rdPartLogin;
//        
//        __weak id wself = self;
//        request.requestCompleteCallback = ^(MFWHttpRequest *request, NSData* responseData, MFWJson* parsedJson, NSError* error)
//        {
//            __strong id sself = wself;
//            if (!error && parsedJson && [parsedJson intValueForKey:@"rc"] != 0)
//            {
//                NSString *errorMessage = [parsedJson stringValueForKey:@"rm"];
//                error = [NSError errorWithDomain:MFWErrorDomain code:[parsedJson intValueForKey:@"rc"] userInfo:@{kMFWErrorInfo_Str_Msg: errorMessage}];
//            }
//            
//            if (sself)
//            {
//                [sself thirdPartLoginFinished:responseData parsedJson:parsedJson error:error];
//            }
//        };
//        
//        [[MFWHttpEngine sharedInstance] addRequest:request];
//    }
//}

//- (BOOL)refreshDefaultUserInfo;
//{
//    MFWHttpRequest *request = [MFWHttpRequest dataRequest];
//    [request.requestParams setValue:@"" forKey:@"x_auth_username"];
//    [request.requestParams setValue:@"" forKey:@"x_auth_password"];
//    request.httpMethod = kRequestHttpMethodPost;
//    request.requestUrl = kAPI_Login;
//    
//    request.requestCompleteCallback = ^(MFWHttpRequest *request, NSData* responseData, MFWJson* parsedJson, NSError* error)
//    {
//        if (!error && parsedJson && [parsedJson intValueForKey:@"rc"] == 0)
//        {
//            MFWJson *jsonData = [parsedJson jsonForKey:@"data"];
//            
////            MFWJson *userJsonData = [jsonData jsonForKey:@"user"];
//            DLog(@"fake user => %@", parsedJson);
//            
//            NSString *oauthToken = [jsonData stringValueForKey:@"oauth_token"];
//            NSString *oauthSecret = [jsonData stringValueForKey:@"oauth_token_secret"];
//            NSString *uid = [jsonData stringValueForKey:@"uid"];
//            
//            if ([@"0" isEqualToString:uid])
//            {
//                [[MFWSdkEnvironment sharedInstance] setupOAuthToken:oauthToken tokenSecret:oauthSecret uid:uid];
//            }
//        }
//        
//    
//    };
//    
//    return [[MFWHttpEngine sharedInstance] addRequest:request];;
//}
@end
